/*
    This file is part of Emu.

    Emu is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Emu is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Emu.  If not, see <http://www.gnu.org/licenses/>. */
#include <QVBoxLayout>
#include <QMargins>
#include <QScrollBar>

#include "esplitter.h"
#include "esplitterhandle.h"

ESplitter::ESplitter() : QSplitter(Qt::Vertical)
{
    /* Create the top window for receiving text. */
    _recvWindow = new QTextEdit;
    _recvWindow->setReadOnly(true);

    /* Create the search bar for finding stuff. This shares space with the top
       window. */
    _searchBar = new ESearchBar(_recvWindow);
    _searchBar->hide();
    _searchWindow = _searchBar->searchWindow();

    /* Create a layout to hold the top window and the find bar. Make sure there
       is as little extra space as possible. */
    QVBoxLayout *topAreaLayout = new QVBoxLayout;
    topAreaLayout->addWidget(_recvWindow);
    topAreaLayout->addWidget(_searchBar);
    topAreaLayout->setContentsMargins(0, 0, 0, 0);
    topAreaLayout->setSpacing(0);

    QWidget *topAreaWidget = new QWidget;
    topAreaWidget->setLayout(topAreaLayout);

    /* The sending (bottom) window. This doesn't accept tabs because servers
       may not show them. Rich text drops are disabled because it's
       difficult to impossible to guarantee that it will show up right on the
       server. */
    _sendWindow = new ETextEdit;
    _sendWindow->setTabChangesFocus(true);
    _sendWindow->setAcceptRichText(false);

    /* Finally, add both widgets to the splitter. */
    this->addWidget(topAreaWidget);
    this->addWidget(_sendWindow);

    setCollapsible(1, true);
    /* Make it so resizes add/take space from the top window, since it benefits
       more from the space gain. Also, it keeps the bottom window from adjusting
       size as much. */
    setStretchFactor(0, 1);
    setStretchFactor(1, 0);
}

void ESplitter::updateFont(QFont newFont)
/* This is called by the mainwindow after creating a session, and also when the
   global font information is updated. */
{
    QFontMetrics fm(newFont);
    QMargins m = _sendWindow->contentsMargins();
    int marginSpace = m.top() + m.bottom();

    _recvWindow->setFont(newFont);
    /* This will only ever show text, so scroll by lines instead of pixels. */
    _recvWindow->verticalScrollBar()->setSingleStep(fm.height());
    /* Ensure that tabs are measured in chars, not in pixels. */
    _recvWindow->setTabStopWidth(fm.averageCharWidth() * 4);

    _sendWindow->setFont(newFont);

    /* The font is set, so how big is the document now? */
    int documentHeight = _sendWindow->document()->size().height();
    int lineSpace = fm.lineSpacing();
    int lineCount = (int)((double)documentHeight / (double)lineSpace);
    /* The first line takes some extra space for...some reason. This is how much
       that is. */
    int extra = documentHeight - (lineSpace * lineCount);
    int newCurrentHeight = (lineCount * lineSpace) + extra + marginSpace;
    int newMinimumHeight = lineSpace + extra + marginSpace;

    /* Both windows must be at least one full line high. */
    _recvWindow->setMinimumHeight(newMinimumHeight);
    _sendWindow->setMinimumHeight(newMinimumHeight);

    /* Handle #1 is the handle between these the two windows. */
    ((ESplitterHandle *)handle(1))->updateFontInfo(lineSpace, extra);

    /* The idea is to keep the bottom window at a steady size, and push the
       rest to the top window. The splitter's size includes the handle, so take
       that out because it's not in either window. */
    int splitterHeight = size().height() - handleWidth();
    QList<int> newSizes;
    newSizes.append(splitterHeight - newCurrentHeight);
    newSizes.append(newCurrentHeight);
    setSizes(newSizes);
}

QSplitterHandle *ESplitter::createHandle()
{
    /* The handles are created when the widgets are added, so _sendWindow has
       already been created. Since the contents margins of _sendWindow will not
       change, they're provided in the constructor for the custom handle. */
    QMargins m = _sendWindow->contentsMargins();
    int lineMargins = m.top() + m.bottom();
    return new ESplitterHandle(this, lineMargins);
}
